import math


########################################################################################
# order manager
# - as there is a latency for sync operation
# - it may not be latest open orders
########################################################################################
class OrderManager:
  def __init__(self):
    self._open_order_dict = {}

  def get_all_working_orders(self, me='ALL'):
    working_orders = []
    if me == 'ALL':
      for orders in self._open_order_dict.values():
        working_orders.extend(orders)
    else:
      if me in self._open_order_dict.keys():
        working_orders.extend(self._open_order_dict[me])
    return working_orders

  def add_order(self, me, event):
    external_order_id = event['external_order_id'] if 'external_order_id' in event else ""
    fill_qty = event['fill_qty']  if 'fill_qty' in event else 0
    order = {
        "market": event["market_type"],
        "exchange": event["exchange_type"],
        #"relative_norm": event["symbol"],,
        "absolute_norm": event["symbol"],
        "native_symbol": event["native_symbol"],
        "proc_order_id": event["proc_order_id"],
        "external_order_id": external_order_id,
        "order_side": event["order_side"],
        "order_price": event["order_price"],
        "order_qty": event["order_qty"],
        "filled_qty": fill_qty,
        "tag": event["tag"],
        "order_created_time": event["event_time"]
    }
    if me not in self._open_order_dict.keys():
      self._open_order_dict[me] = [order]
    else:
      self._open_order_dict[me].append(order)

  def del_order(self, me, event):
    if me not in self._open_order_dict.keys():
      return
    working_orders = []
    orders = self._open_order_dict[me]
    for order in orders:
      if event['proc_order_id'] == order['proc_order_id']:
        continue
      if 'external_order_id' in event and 'external_order_id' in order and \
          event['external_order_id'] == order['external_order_id']:
        continue
      working_orders.append(order)
    self._open_order_dict[me] = working_orders

  def on_order_update(self, update):
    order = update.as_dict()
    event = order['event']
    event_type = event['type']
    if event_type in ["ORDER_SUBMITTED", "ORDER_ACCEPTED"]:
      me = "{}:{}".format(order['market'], order['exchange'])
      self.add_order(me, event)
    elif event_type in ["ORDER_REJECTED", "CANCEL_CONFIRMED"]:
      me = "{}:{}".format(order['market'], order['exchange'])
      self.del_order(me, event)
    elif event_type == "ORDER_FILLED":
      if math.isclose(event['order_qty'], event['fill_qty']):
        me = "{}:{}".format(order['market'], order['exchange'])
        self.del_order(me, event)
    else:
      pass

  def on_order_snapshot(self, snapshot):
    self._open_order_dict.clear()
    for order in snapshot.order_snapshot:
      me = "{}:{}".format(order['market'], order['exchange'])
      if me not in self._open_order_dict.keys():
        self._open_order_dict[me] = [order]
      else:
        self._open_order_dict[me].append(order)
    #print(self._open_order_dict)
